feat(Android, FormSheet v5): Setup TouchHandler on Dialog window#4204
Conversation
There was a problem hiding this comment.
Pull request overview
This PR fixes touch/pointer event dispatch for the Android FormSheet (rendered inside a native Dialog) by turning the dialog’s content container into its own React RootView, with local JSTouchDispatcher / JSPointerDispatcher instances to route MotionEvents into React Native correctly.
Changes:
- Make
FormSheetContentViewimplementRootViewand forward touch/hover/gesture events toJSTouchDispatcherandJSPointerDispatcher. - Make
FormSheetHostimplementReactPointerEventsViewwithpointerEvents = NONEso the “empty” host in the main window doesn’t block hit-testing behind it.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| android/src/main/java/com/swmansion/rnscreens/gamma/modals/formsheet/FormSheetHost.kt | Marks the host view as non-hit-testable in the main window via pointerEvents = NONE. |
| android/src/main/java/com/swmansion/rnscreens/gamma/modals/formsheet/FormSheetContentView.kt | Adds RootView-style touch/pointer dispatching so dialog-window interactions reach the RN event system. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
kmichalikk
left a comment
There was a problem hiding this comment.
runtime seems ok from quick glance, no further comments from me, but please look at what copilot added
kligarski
left a comment
There was a problem hiding this comment.
There seem to be some problems with fast refresh and dynamically adding/removing views.
Screen.Recording.2026-06-24.at.14.57.34.mov
There was a problem hiding this comment.
It seems like this class will be really closely tied to react so my comment from previous PR might be difficult to implement but maybe we can in the future pass this view (part of react impl) to container constructor (native impl) and everything will be nicely separated.
I see, will fix that in a followup: https://github.com/software-mansion/react-native-screens-labs/issues/1580 , added to current iteration |
645b17c to
937b641
Compare
Description
This PR implements the touch and pointer event handling for the FormSheet by making the ContentView to act as a separate React RootView.
When rendering React Native components inside a native Dialog, the views are rendered in a completely separate window. This breaks touch event dispatching because React Native's main ReactRootView is completely unaware of this detached window.
To solve this, we make
FormSheetContentViewimplement theRootViewinterface and instantiate its ownJSTouchDispatcherandJSPointerDispatcher. By overriding the standard Android touch and hover methods and feeding the MotionEvents directly into these local dispatchers, we successfully forward user interactions from the dialog's window into the RN event system.Because FormSheetContentView establishes itself as a new, independent
RootViewboundary, theMotionEventcoordinates supplied by theAndroidframework are naturally scoped to the bounds of the dialog's window, resulting in the proper coordinate mapping for the React children without any shadow tree contentOriginOffset corrections.Closes: https://github.com/software-mansion/react-native-screens-labs/issues/1548
Changes
FormSheetContentViewnow acts as aRootView.JSTouchDispatcherfrom RN core modal implementation to handle standard MotionEventsJSPointerDispatcherfrom RN core modal implementation to handle pointer events and hover statesBefore & after - visual documentation
formsheet-pressables-android.mov
Test plan
Base test for formsheets, verify that pressables are working properly.
Checklist